home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
a_code01.zip
/
DB_WINL.ASM
< prev
Wrap
Assembly Source File
|
1993-04-07
|
17KB
|
657 lines
dosseg
locals
.model large
extrn _checksnow:byte
extrn _scrwid:byte
extrn _scrhgt:byte
extrn _cmono:dword
.code
public _dispw
public _initblk
public _restline
public _displine
public _dispattr
;-----------------------------------------------------------------------------
; MACRO TO TRANSLATE MONO ATTRIBUTE
;-----------------------------------------------------------------------------
reset_attrib macro
push es
push di
push ax
les di,dword ptr cs:tomonoofs
mov al,ah
xor ah,ah
add di,ax
pop ax
mov ah,es:[di]
pop di
pop es
endm
;-----------------------------------------------------------------------------
; LOCAL STORAGE FOR ATTRIBUTE TRANSLATE TABLE ADDRESS
;-----------------------------------------------------------------------------
tomonoofs dw 0
tomonobase dw 0
;-----------------------------------------------------------------------------
; WRITE CHARACTER TO VIDEO RAM WITH RETRACE SYNCH
;-----------------------------------------------------------------------------
; Writes the char/attr specified to video ram synching to the horizintal
; and vertical retrace on CGA.
; Attributes and characters of 0 are not written.
;
; Input:
; AX - char/attr to write
; ES:DI - video ram destination address
;
; Output:
; ES:DI - just past word written
;
; Destroys:
; None
;
;-----------------------------------------------------------------------------
vidchr proc near
push bp
push dx
mov dx,3DAh ; address CGA status port
mov bp,ax ; save char/attr
or ah,ah ; is attribute is zero
je @@charonly ; y - only output the char
or al,al ; is char NUL
je @@attronly ; y - only output the attr
@@charattr: ; WRITE CHARACTER/ATTRIBUTE
@@cawait1: in al,dx ; wait for horz retrace to
rcr al,1 ; ensure proper synch
jnb @@cawait1
@@cawait2: in al,dx ; wait for no horz retrace
and al,9 ; or vert retrace
shr al,1
jnz @@cawrite
jb @@cawait2
cli
@@cawait3: in al,dx ; wait for retrace
rcr al,1
jnb @@cawait3
@@cawrite: mov ax,bp ; store word
stosw
sti
jmp short @@fin
@@charonly: ; WRITE CHARACTER ONLY
@@cowait1: in al,dx ; wait for horz retrace to
rcr al,1 ; ensure proper synch
jnb @@cowait1
@@cowait2: in al,dx ; wait for no horz retrace
and al,9 ; or vert retrace
shr al,1
jnz @@cowrite
jb @@cowait2
cli
@@cowait3: in al,dx ; wait for retrace
rcr al,1
jnb @@cowait3
@@cowrite: mov ax,bp ; store character
stosb
sti
inc di ; skip attribute
jmp short @@fin
@@attronly: ; WRITE ATTRIBUTE ONLY
@@aowait1: in al,dx ; wait for horz retrace to
rcr al,1 ; ensure proper synch
jnb @@aowait1
@@aowait2: in al,dx ; wait for no horz retrace
and al,9 ; or vert retrace
shr al,1
jnz @@aowrite
jb @@aowait2
cli
@@aowait3: in al,dx ; wait for retrace
rcr al,1
jnb @@aowait3
@@aowrite: mov ax,bp ; store attribute
inc di ; skip character
mov es:[di],ah
sti
inc di ; move to next char
@@fin: pop dx
pop bp
ret
vidchr endp
;-----------------------------------------------------------------------------
; WRITE STRING TO VIDEO RAM WITH RETRACE SYNCH
;-----------------------------------------------------------------------------
; Writes the char/attrs specified to video ram synching to the horizintal
; and vertical retrace on CGA.
;
; Input:
; CX - number of words to write
; DS:SI - source address
; ES:DI - video ram destination address
;
; Output:
; DS:SI - just past last word read
; ES:DI - just past last word written
; CX - 0
;
; Destroys:
; None
;
;-----------------------------------------------------------------------------
vidstr proc near
push bp
push ax
push dx
mov dx,3DAh ; address CGA status port
@@wait0: in al,dx ; wait for horz retrace to
rcr al,1 ; ensure proper synch
jnb @@wait0
@@writeloop: lodsw ; get char/attr
mov bp,ax ; save word to write
@@wait1: in al,dx ; wait for no horz retrace
and al,9 ; or vert retrace
shr al,1
jnz @@write
jb @@wait1
cli
@@wait2: in al,dx ; wait for retrace
rcr al,1
jnb @@wait2
@@write: mov ax,bp ; store word
stosw
sti
loop @@writeloop
pop dx
pop ax
pop bp
ret
vidstr endp
;-----------------------------------------------------------------------------
; void dispw(byte x, byte y, byte w, byte h, byte _w, ptr vram, ptr winb);
;-----------------------------------------------------------------------------
; Displays window buffer contents on video ram
;
;-----------------------------------------------------------------------------
_dispw proc
arg x:byte, y:byte, w:byte, h:byte, _w:byte, vram:dword, winb:dword
push bp
mov bp,sp ; link stack
push si ; save regs
push di
push ds
mov ax,seg _cmono ; put attribute base in local
mov ds,ax ; storage in CS:
les di,_cmono
mov cs:tomonobase,es
mov cs:tomonoofs,di
les di,vram ; get video ram addr
mov bx,es
xor bx,0B800h ; check for CGA screen dest
jnz @@nosnowcheck ; n - ignore checksnow
mov ax,seg _checksnow
mov ax,ds
mov bl,_checksnow ; load checksnow value
xor bh,bh
jmp short @@snowchecked ; go do
@@nosnowcheck: xor bx,bx
@@snowchecked: push bx ; save synch flag on stack
mov ax,seg _scrwid ; get video screen width
mov ds,ax
mov al,_scrwid
xor ah,ah
shl ax,1 ; take attributes into account
push ax ; save width on stack
lds si,winb ; DS:SI = window block address
mov dl,x
dec dl ; DL = x-1 zero ofs
mov dh,y
dec dh ; DH = y-1
mul dh ; calc location vram ofs
add al,dl ; add in col ofs
adc ah,+00
add al,dl
adc ah,+00
mov di,ax ; ES:DI dest in video ram
mov cl,w
xor ch,ch ; CX = displayable chars/line
mov dl,h ; DL = displayable lines
pop ax ; get screen width off stack
sub al,cl
sub al,cl
xor ah,ah ; AX = next line vram inc
mov bl,_w
shl bl,1
xor bh,bh ; BX = next line winb inc
cld ; go forwards
pop bp ; BP = synch flag
jcxz @@fin ; exit if no lines to do
or dl,dl ; see is any lines to do
jz @@fin ; n - nothing to do
@@disploop: push cx ; save chars/line
or bp,bp ; check for synch required
jz @@nosnow ; n
@@snow: call vidstr ; y - avoid snow
jmp short @@skip
@@nosnow: push ax ; save vram inc
@@repeat: lodsw ; get buffer word
reset_attrib
stosw ; store to vram
loop @@repeat ; repeat for all chars/line
pop ax ; get vram inc
@@skip: add si,bx ; move to next winb line
add di,ax ; move to next vram line
pop cx ; restore chars/line
dec dl ; reduce lines to do
ja @@disploop ; continue for all lines
@@fin: pop ds ; restore regs
pop di
pop si
pop bp
ret
_dispw endp
;-----------------------------------------------------------------------------
; void initblk(word len, char chr, byte color, ptr winb);
;-----------------------------------------------------------------------------
; Fills window buffer with specified char and attribute
;
;-----------------------------------------------------------------------------
_initblk proc
arg len:word,chr:byte,color:byte,winb:dword
push bp
mov bp,sp ; link stack
push si ; save regs
push di
push ds
les di,winb ; ES:DI = window block addr
mov al,chr
mov ah,color
mov cx,len
jcxz @@fin
cld ; go forwards
rep stosw ; fill window buffer
@@fin: pop ds ; restore regs
pop di
pop si
pop bp
ret
_initblk endp
;-----------------------------------------------------------------------------
; void restline(byte x, byte y, byte len, byte orient, ptr actv, ptr savv);
;-----------------------------------------------------------------------------
; Transfers line from save video to active video in orientation specified
;
;-----------------------------------------------------------------------------
_restline proc
arg x:byte,y:byte,len:byte,orient:byte,actv:dword,savv:dword
push bp
mov bp,sp ; link stack
push si ; save regs
push di
push ds
mov ax,seg _cmono ; put attribute base in local
mov ds,ax ; storage in CS:
les di,_cmono
mov cs:tomonobase,es
mov cs:tomonoofs,di
mov ax,seg _scrwid ; get video screen width
mov ds,ax
mov al,_scrwid
xor ah,ah
shl ax,1 ; AX = video ram width
push ax ; save on stack
mov bx,seg _checksnow ; get synch flag
mov ds,bx
mov bl,_checksnow
xor bh,bh ; BX = synch flag
push bx ; save on stack
les di,actv ; ES:DI = active video base
lds si,savv ; DS:SI = save video base
mov dl,x
dec dl ; DL = x-1 zero ofs
mov dh,y
dec dh ; DH = y-1
mul dh ; calc location ofs
add al,dl
adc ah,0
add al,dl
adc ah,0
mov di,ax ; ES:DI = active video loc
mov si,ax ; DS:SI = save video loc
cld ; go forwards
mov bl,orient
xor bh,bh
mov cl,len
xor ch,ch
or cx,cx ; any to do
jnz @@sometodo ; y
pop ax ; cleanup stack
pop ax
jmp short @@fin
@@sometodo: pop bp ; get synch flag
shr bx,1 ; check direction
jb @@horizontal ; go horizontally
@@vertical: pop bx ; get width
sub bx,2
@@vwriteloop: lodsw
or bp,bp
jz @@vnosnow
@@vsnow: call vidchr ; CGA interference avoidance
jmp short @@vskip
@@vnosnow: reset_attrib
stosw
@@vskip: add di,bx
add si,bx
loop @@vwriteloop
jmp short @@fin
@@horizontal: or bp,bp ; check synch flag
jz @@hnosnow
@@hsnow: call vidstr ; CGA interference avoidance
jmp short @@hskip
@@hnosnow: lodsw
reset_attrib
stosw
loop @@hnosnow
@@hskip: pop bx ; width still on stack
@@fin: pop ds ; restore regs
pop di
pop si
pop bp
ret
_restline endp
;-----------------------------------------------------------------------------
; DETERMINE STRING LENGTH
;-----------------------------------------------------------------------------
; Input:
; DS:SI - pointer to string
; Output:
; CX - string length
; Destroys:
; none
;
;-----------------------------------------------------------------------------
strlen proc near
push si
xor cx,cx ; init to empty string
@@loop: cmp byte ptr ds:[si],0 ; is char NUL
je @@fin ; y - done
inc cx ; bump char count
inc si ; bump char pointer
jmp short @@loop ; keep going
@@fin: pop si
ret
strlen endp
;-----------------------------------------------------------------------------
; void displine(byte x, byte y, byte colr, byte orient, byte w, word _di,
; ptr destv, ptr s);
;-----------------------------------------------------------------------------
; Writes string to video buffer in orientation specified
;
;-----------------------------------------------------------------------------
_displine proc
arg x:byte,y:byte,colr:byte,orient:byte,w:byte,_di:word,destv:dword,s:dword
push bp
mov bp,sp ; link stack
push si ; save regs
push di
push ds
les di,destv ; ES:DI - dest video base
mov bx,es
xor bx,0B800h ; is dest in CGA ram
jnz @@nosnowcheck ; n - so ignore checksnow
mov bx,seg _checksnow
mov bl,_checksnow ; load checksnow value
xor bh,bh
jmp short @@snowchecked
@@nosnowcheck: xor bx,bx
@@snowchecked: mov ax,_di ; get max window _di
push ax ; save on stack
push bx ; save synch flag on stack
mov al,w
xor ah,ah
shl ax,1 ; AX - width in video ram
push ax ; save for with vert lines
lds si,s ; DS:SI - source string
mov dl,x
dec dl ; DL = x-1 zero ofs
mov dh,y
dec dh ; DH = y-1
mul dh ; calc location ofs
add al,dl
adc ah,0
add al,dl
adc ah,0
mov di,ax ; ES:DI - dest ofs
cld ; go forwards
call strlen ; get string length
or cx,cx ; any chars to do
jnz @@sometodo
pop ax ; cleanup stack
pop ax
pop ax
jmp @@finnocx
@@sometodo: mov bl,orient ; BX = orientation
xor bh,bh
shr bx,1
jb @@horizontal
@@vertical: pop bx ; get window width off stack
sub bx,2
jmp short @@setup
@@horizontal: pop ax ; get window width off stack
@@setup: mov al,[si] ; first character
mov ah,colr ; AH = color
pop dx ; DX = synch flag
pop bp ; BP = max screen size
@@test255: cmp al,0FFh ; check for special chars
jne @@outchar ; n
dec cx
inc si
mov al,[si]
cmp cx,3 ; enough chars for contol code
jb @@fin ; n - exit
cmp al,2 ; 2 = change attribute
je @@changeattr
cmp al,1 ; 1 = repeat character
je @@repeatchar
jmp short @@outchar
@@changeattr: inc si
mov ah,[si] ; new attribute
inc si
mov al,[si] ; next character into AL
sub cx,2
jmp short @@test255 ; see if char is control code
@@repeatchar: sub cx,2
push cx ; save count
mov dh,1 ; show in repeat
inc si
mov cl,[si] ; get count
inc si
mov al,[si] ; get char
xor ch,ch
jcxz @@skip ; aviod a zero repeat count
@@outchar: or dl,dl ; see if avoid snow
jz @@nosnow ; n
@@snow: call vidchr ; CGA interference avoidance
jmp short @@skip
@@nosnow: or ah,ah ; see if attrib supplied
jz @@charonly ; n - output character only
or al,al ; see if character supplied
jz @@attronly ; n - output attrribute only
@@charattr: stosw ; output the char & attr pair
jmp short @@skip
@@charonly: stosb
inc di ; step past screen attr
jmp short @@skip
@@attronly: inc di ; step past screen char
mov es:[di],ah ; put only the attr
inc di ; move on to next char
@@skip: add di,bx ; add in width for vert
cmp bp,di
jbe @@fin ; at end of window so stop
or dh,dh ; is this a rep print
jz @@normal ; n
cmp cx,1 ; y
jle @@repeatfin
loop @@outchar
@@repeatfin: pop cx
xor dh,dh
@@normal: inc si ; point to next char to disp
mov al,[si] ; get char into AL
loop @@test255
@@fin: or dh,dh ; is cx still on stack
jz @@finnocx ; n
pop cx ; y - get it off
@@finnocx: pop ds ; restore regs
pop di
pop si
pop bp
ret
_displine endp
;-----------------------------------------------------------------------------
; void dispattr(byte x, byte y, byte colr, byte orient, byte w, word _di,
; ptr destv, byte n);
;-----------------------------------------------------------------------------
; Sets attribute on number of characters specified
;
;-----------------------------------------------------------------------------
_dispattr proc
arg x:byte,y:byte,colr:byte,orient:byte,w:byte,_di:word,destv:dword,n:byte
push bp
mov bp,sp ; link stack
push di
les di,destv ; ES:DI - dest video base
mov bx,es
xor bx,0B800h ; is dest in CGA ram
jnz @@nosnowcheck ; n - so ignore checksnow
mov bx,seg _checksnow
mov bl,_checksnow ; load checksnow value
xor bh,bh
jmp short @@snowchecked
@@nosnowcheck: xor bx,bx
@@snowchecked: mov ax,_di ; get max window _di
push ax ; save on stack
push bx ; save synch flag on stack
mov al,w
xor ah,ah
shl ax,1 ; AX - width in video ram
push ax ; save for with vert lines
mov dl,x
dec dl ; DL = x-1 zero ofs
mov dh,y
dec dh ; DH = y-1
mul dh ; calc location ofs
add al,dl
adc ah,0
add al,dl
adc ah,0
mov di,ax ; ES:DI - dest ofs
cld ; go forwards
mov cl,n
xor ch,ch
or cx,cx ; any to do
jnz @@sometodo
pop ax ; cleanup stack
pop ax
pop ax
jmp @@fin
@@sometodo: mov bl,orient ; BX = orientation
xor bh,bh
shr bx,1
jb @@horiz
@@vert: pop bx ; get window width off stack
sub bx,2
jmp short @@setup
@@horiz: pop ax ; get window width off stack
@@setup: mov al,0 ; AL = NUL - dont write chars
mov ah,colr ; AH = color
pop dx ; DX = synch flag
pop bp ; BP = max screen size
@@outattr: or dl,dl ; see if avoid snow
jz @@nosnow ; n
@@snow: call vidchr ; CGA interference avoidance
jmp short @@skip
@@nosnow: inc di ; step past screen char
mov es:[di],ah ; put only the attr
inc di ; move on to next char
@@skip: add di,bx ; add in width for vert
cmp bp,di
jbe @@fin ; at end of window so stop
loop @@outattr
@@fin: pop di
pop bp
ret
_dispattr endp
;-----------------------------------------------------------------------------
end